package org.springblade.oa.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.springblade.core.mp.support.SqlKeyword;
import org.springblade.core.secure.BladeUser;
import org.springblade.core.tool.api.R;
import org.springblade.core.tool.utils.BeanUtil;
import org.springblade.core.tool.utils.Func;
import org.springblade.oa.service.IBxService;
import org.springblade.oa.vo.*;
import org.springblade.system.feign.IDictClient;
import org.springblade.system.feign.ISysClient;
import org.springblade.system.user.entity.UserInfo;
import org.springblade.system.user.feign.IUserClient;
import lombok.AllArgsConstructor;
import org.springblade.core.mp.base.BaseServiceImpl;
import org.springblade.oa.mapper.ExpenseAccountMapper;
import org.springblade.oa.service.IExpenseAccountService;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collector;
import java.util.stream.Collectors;

/**
 * @author LK
 * @version 1.0.0
 * @Title: ExpenseAccounServiceImpl.java
 * @Description:   报销服务实现
 * @date 2020/1/13 11:56
 */
@Service
@AllArgsConstructor
public class ExpenseAccountServiceImpl extends BaseServiceImpl<ExpenseAccountMapper, ExpenseAccount> implements IExpenseAccountService {

	ExpenseAccountMapper expenseAccountMapper;

	private IUserClient userClient;

	private IDictClient dictClient;

	private ISysClient sysClient;
	private IBxService bxService;
	/**
	 * 获取报销列表
	 *
	 * @param expenseAccount 报销对象
	 * @param user           用户对象
	 * @param pageQuery      分页查询参数
	 * @return
	 */
	@Override
	public IPage<ExpenseAccount> getExpenseAccountList(ExpenseAccount expenseAccount, BladeUser user, PageQuery pageQuery) {
		//获取用户信息
		R<UserInfo> userInfo = userClient.userInfo(user.getUserId().longValue());
		List<String> roleArr = null;
		if (Func.isNotEmpty(user)) {
			String roles = user.getRoleId();
			if (Func.isNotBlank(roles)) {
				roleArr = Arrays.asList(user.getRoleId().split(","));
			}
			if ("2".equals(expenseAccount.getMenuType())) {
				if (roleArr.contains("11")){
					expenseAccount.setDeptId(userInfo.getData().getUser().getDpprovalDeptId());
					expenseAccount.setStatusTypeList("2,3,4,5,6");
				} else if (roleArr.contains("8")) {
					expenseAccount.setDeptId(userInfo.getData().getUser().getDeptId());
					expenseAccount.setStatusTypeList("2,3,4,5,6");
				} else {
					expenseAccount.setStatusTypeList("3,4,5,6");
				}

			} else {
				expenseAccount.setEaUserId(user.getUserId());
			}


		/*	if (roleArr.contains("1")||roleArr.contains("3")) {
				expenseAccount.setStatusTypeList("4,5,6");
			}else if(roleArr.contains("4")||roleArr.contains("5")){
				expenseAccount.setStatusTypeList("3,4,5,6");
			} else if (roleArr.contains("8")||roleArr.contains("11")){
				expenseAccount.setDeptId(userInfo.getData().getUser().getDeptId());
				expenseAccount.setStatusTypeList("2,3,4,5,6");
			}
		*/

			//获取项目名称字典
			String projectName = expenseAccountMapper.getProjectName(expenseAccount.getProjectId());
			expenseAccount.setProjectName(projectName);
		}
		//创建分页对象初始化参数
		Page<ExpenseAccount> page = new MyPage<>();
		page.setAsc(Func.toStrArray(SqlKeyword.filter(pageQuery.getAscs())));
		page.setDesc(Func.toStrArray(SqlKeyword.filter(pageQuery.getDescs())));
		pageQuery.setCurrentIndex((pageQuery.getCurrent() - 1) * pageQuery.getSize());
		//查询放入列表数据
		List<ExpenseAccount> list=new ArrayList<>();
		//角色是会计或出纳又是部门审批人
		if (roleArr.contains("11")&&(roleArr.contains("5")||roleArr.contains("4"))){
			ExpenseAccount e = BeanUtil.copy(expenseAccount, ExpenseAccount.class);
			expenseAccount.setDeptId(userInfo.getData().getUser().getDpprovalDeptId());
			expenseAccount.setStatusTypeList("2");
			e.setStatusTypeList("3,4,5,6");
			e.setDeptId(null);
			list = expenseAccountMapper.getExpenseAccountList2(expenseAccount,e, pageQuery);page.setSize(0);
			pageQuery.setCurrent(null);
			pageQuery.setSize(null);
			List<ExpenseAccount> eaSizeList = expenseAccountMapper.getExpenseAccountList2(expenseAccount, e, pageQuery);
			page.setTotal(eaSizeList.size());
			BigDecimal sumAmount = eaSizeList.stream().map(ExpenseAccount::getEaMoney).reduce(BigDecimal.ZERO, BigDecimal::add);
			((MyPage<ExpenseAccount>) page).setSumAmount((sumAmount).doubleValue());
		}else {
			list = expenseAccountMapper.getExpenseAccountList(expenseAccount, pageQuery);
			Map map = expenseAccountMapper.getExpenseAccountSumTotalAndSumAmount(expenseAccount, pageQuery);
			page.setTotal(Long.valueOf(map.get("sumTotal").toString()));
			if (map.containsKey("sumAmount")) {
				((MyPage<ExpenseAccount>) page).setSumAmount(((BigDecimal) map.get("sumAmount")).doubleValue());
			}
		}
		List<String> deptList = null;
		StringBuffer deptNames;
		String deptId;
		for (ExpenseAccount account : list) {
			account.setEaStatusName(dictClient.getValue("bx_status", Integer.valueOf( account.getEaStatus() ) ).getData());
			account.setEaCompanyName(dictClient.getValue("bx_company", account.getEaCompany()).getData());
			account.setEaTypeName(dictClient.getValue("bx_type", account.getEaType()).getData());
			//account.setEaUserName(userClient.userInfo(account.getEaUserId().longValue()).getData().getUser().getRealName());
			account.setEaUserName( baseMapper.getUserById(account.getEaUserId()));

			deptId = account.getDeptId();
			deptNames = new StringBuffer();
			if (Func.isNotBlank(deptId)) {
				deptList = Arrays.asList(account.getDeptId().split(","));
				for (String s : deptList) {
					deptNames.append(sysClient.getDeptName(Integer.parseInt(s)));
				}
			}
			account.setDeptName(deptNames.toString());
		}
		page.setRecords(list);
		//查询总条数以及当前查询条件下报销总金额

		return page;
	}

	/**
	 * 获取项目名称列表
	 *
	 * @param eaCompany 报销公司id
	 * @return
	 */
	@Override
	public Map getProjectNameList(Integer eaCompany) {
		//获取报销单位名称
		String leader = dictClient.getValue("bx_company", eaCompany).getData();
		//获取项目编号和项目名称
		List<Map<String, String>> mapList = expenseAccountMapper.getProjectNameList(leader);
		Map<String, String> projectNameMap = new HashMap();
		for (Map<String, String> map : mapList) {
			projectNameMap.put(map.get("projectId"), map.get("projectName"));
		}
		return projectNameMap;
	}

	/**
	 * 根据项目编号获取项目名称
	 *
	 * @param code 项目编号
	 * @return
	 */
	@Override
	public String getProjectName(String code) {
		return expenseAccountMapper.getProjectName(code);
	}
	@Override
	public String getProjectAbbName(String code) {
		return expenseAccountMapper.getProjectAbbName(code);
	}


	@Override
	public Map getPrintData(List<Map<String, Object>> printData) {
		DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
		DateFormat mmdd = new SimpleDateFormat("MM月dd日");
		Map<String, Object> printDataMap = new HashMap();
		List list = new ArrayList();
		Map<String, Object> map = null;
		List details = null;
		List detailstb = null;
		List fare = null;
		List hotelExpense = null;
		List subsidy = null;
		List other = null;
		Integer fplx = 1;
		for (Map<String, Object> printDatum : printData) {
			map = new HashMap();
			BxVo bxvo = (BxVo) printDatum.get("bx");
			//类型
			Integer eaType = bxvo.getBxlx();
			details = new ArrayList();
			detailstb = new ArrayList();
			fare = new ArrayList();
			hotelExpense = new ArrayList();
			subsidy = new ArrayList<>();
			other = new ArrayList<>();
			Map<String, Object> map1 = null;
			Map<String, Object> map2 = null;
			Map<String, Object> map3 = null;
			Map<String, Object> map4 = null;
			Map<String, Object> map1tb = null;
			Map<String, Object> maptb = null;
			BxxcmxVO bxxcmxVO;
			BxfymxVO bxfymxVO;
			BxzszpmxVO bxzszpmxVO;
			if (1 == eaType) {//行程
				map.put("deductibleTax",bxvo.getDeductibleTax());
				map.put("untaxPrice",bxvo.getUntaxPrice());
				//票据 数量
				map.put("billCount",bxvo.getBillCount());
				map.put("ccsyName",bxvo.getCcsyName());
				map.put("type", "travel");
				//报销ID
				map.put("no", bxvo.getBxbh());
				//报销日期
				map.put("bxrq", bxvo.getBxrq());
				//部门
				map.put("department", bxvo.getBmidName());
				//审核人
				map.put("shperson", bxvo.getShrqm());
				//报销人
				map.put("bxperson", bxvo.getBxrName());
				//大写
				map.put("minusculeTotal", bxvo.getBxzje());
				//小写
				map.put("capitalTotal", bxvo.getBxzjedx());
				//差旅详情摘要金额
				List<Object> bxxcmxList = (List) printDatum.get("bxxcmxList");
				BxxcmxVO xc = (BxxcmxVO) bxxcmxList.get(0);
				for (Object o : bxxcmxList) {
					map1 = new HashMap<>();
					map2 = new HashMap<>();
					map3 = new HashMap<>();
					map4 = new HashMap<>();
					bxxcmxVO = (BxxcmxVO) o;
					map1.put("time", dateFormat.format(bxxcmxVO.getKssj()));
					map1.put("place", bxxcmxVO.getQd() + "-" + bxxcmxVO.getZd());
					map1.put("train", bxxcmxVO.getHcje());
					map1.put("aircraft", bxxcmxVO.getFjje());
					map1.put("bus", bxxcmxVO.getJcdbje());
					map1.put("other", bxxcmxVO.getQtje());
					fare.add(map1);
					map2.put("place", bxxcmxVO.getBtdd());
					map2.put("day", bxxcmxVO.getBtts());
					map2.put("norm", bxxcmxVO.getBtbz());
					map2.put("money", bxxcmxVO.getBtje());
					subsidy.add(map2);
					map3.put("content", bxxcmxVO.getQtbz());
					map3.put("money", bxxcmxVO.getQtje());
					other.add(map3);
					map4.put("place", bxxcmxVO.getZsdd());
					map4.put("day", bxxcmxVO.getZsts());
					map4.put("money", bxxcmxVO.getZsje());
					hotelExpense.add(map4);
				}

				//项目编号
				map.put("projectNo", getSynthesisProject(bxvo.getId()).get("projectId"));
				map.put("projectNum", getSynthesisProject(bxvo.getId()).get("projectId"));
				map.put("projectName", getSynthesisProject(bxvo.getId()).get("projectName"));
				map.put("projectNameAbb", getSynthesisProject(bxvo.getId()).get("projectNameAbb"));
				map.put("hotelExpense", hotelExpense);
				map.put("fare", fare);
				map.put("subsidy", subsidy);
				map.put("other", other);

			} else if (2 == eaType) {//费用
				List<Object> bxfymxList = (List) printDatum.get("bxfymxList");
				for (Object o : bxfymxList) {
					map1 = new HashMap<>();
					map1tb = new HashMap<>();
					maptb = new HashMap<>();
					bxfymxVO = (BxfymxVO) o;
					fplx = bxfymxVO.getFplx();

					map1.put("content", bxfymxVO.getFylxName());
					map1.put("money", bxfymxVO.getFybxdje());
					details.add(map1);

					map1tb.put("content", bxfymxVO.getTbfylxName());
					map1tb.put("money", bxfymxVO.getTbfybxdje());
					detailstb.add(map1tb);
				}
				//费用
				//行程事由
				map.put("ccsyName",bxvo.getCcsyName());
				//票据数量
				map.put("billCount",bxvo.getBillCount());
				map.put("iszs", 0);//是否住宿
				map.put("type", "money");
				map.put("no", bxvo.getBxbh());//报销编号
				map.put("bxperson", bxvo.getBxrName());//报销人
				map.put("shperson", bxvo.getShrqm());//审核人
				map.put("projectDate", dateFormat.format(bxvo.getUpdateTime()));//项目时间
				map.put("total", bxvo.getBxzje());	//总计
//				map.put("projectNo", getSynthesisProject(bxvo.getId()).get("projectId"));//项目编号
				map.put("projectNum", getSynthesisProject(bxvo.getId()).get("projectId"));
				map.put("projectName", getSynthesisProject(bxvo.getId()).get("projectName"));
				map.put("projectNameAbb", getSynthesisProject(bxvo.getId()).get("projectNameAbb"));
				map.put("details", details);
				map.put("projectNo", bxvo.getBmidName());//部门名称
				if(0 == fplx){
					map.put("fplx", 0);
				}else{
					map.put("fplx", 1);
				}
				map.put("sfglxc","0");//是否关联行程

				maptb.put("type", "money");
				maptb.put("no", bxvo.getBxbh());//报销编号
				maptb.put("bxperson", bxvo.getBxrName());//报销人
				maptb.put("shperson", bxvo.getShrqm());//审核人
				maptb.put("projectDate", dateFormat.format(bxvo.getUpdateTime()));//项目时间
				maptb.put("total", bxvo.getTbbxzje());	//总计
//				maptb.put("projectNo", getSynthesisProject(bxvo.getId()).get("projectId"));//项目编号
				maptb.put("projectNum", getSynthesisProject(bxvo.getId()).get("projectId"));
				maptb.put("projectName", getSynthesisProject(bxvo.getId()).get("projectName"));
				maptb.put("projectNameAbb", getSynthesisProject(bxvo.getId()).get("projectNameAbb"));
				maptb.put("projectNo", bxvo.getBmidName());//部门名称
				maptb.put("details", detailstb);
				maptb.put("fplx", 1);
				maptb.put("sfglxc","0");//是否关联行程


			} else if (3 == eaType) {//住宿
				//行程事由
				map.put("ccsyName",bxvo.getCcsyName());
				//票据 数量
				map.put("billCount",bxvo.getBillCount());
				map.put("iszs", 1);//是否住宿
				map.put("type", "money");
				//报销编号
				map.put("no", bxvo.getBxbh());
				//部门
				map.put("department", bxvo.getBmidName());
				//审核人
				map.put("shperson", bxvo.getShrqm());
				//报销人
				map.put("bxperson", bxvo.getBxrName());
				//项目时间
				map.put("projectDate", dateFormat.format(bxvo.getBxrq()));
				//总计
				map.put("total", bxvo.getBxzje());
				map.put("fare", fare);
				//专票
				String glbxbh ="";
				String bmmc = "";
				List<Object> bxzszpmxList = (List) printDatum.get("bxzszpmxList");
				for (Object o : bxzszpmxList) {
					map1 = new HashMap<>();
					bxzszpmxVO = (BxzszpmxVO) o;
					if(bxzszpmxVO.getSfglxc()==1){
						glbxbh =  bxService.getById( bxzszpmxVO.getClbxdid()).getBxbh();
						map.put("projectNo",glbxbh);
					}else{
						bmmc = sysClient.getDeptName( bxService.getById( bxzszpmxVO.getBxdid()).getBmid() ) ;
						map.put("projectNo",bmmc);
					}
					map1.put("content", mmdd.format(bxzszpmxVO.getKssj()) + "-" + mmdd.format(bxzszpmxVO.getJssj()) + "(" + bxzszpmxVO.getDd() + ")");
					map1.put("money", bxzszpmxVO.getJe());
					//是否关联行程
					map.put("sfglxc",bxzszpmxVO.getSfglxc());
					details.add(map1);
				}
				//项目编号
//				map.put("glbxbh", glbxbh);
//				map.put("projectNo", getSynthesisProject(bxvo.getId()).get("projectId"));
				map.put("projectNum", getSynthesisProject(bxvo.getId()).get("projectId"));
				map.put("projectName", getSynthesisProject(bxvo.getId()).get("projectName"));
				map.put("projectNameAbb", getSynthesisProject(bxvo.getId()).get("projectNameAbb"));
				map.put("details", details);
			}
			list.add(map);
			if (fplx==0){
				list.add(maptb);
				fplx = 1;
			}
		}
		printDataMap.put("printData", list);
		return printDataMap;
	}

	@Override
	public Map<String, String> getSynthesisProject(Integer bxdid) {
		return expenseAccountMapper.getSynthesisProject(bxdid);
	}

	@Override
	public List<Map<String, Object>> getUser(Map<String,Object> params) {
		return expenseAccountMapper.getUser(params);
	}

	@Override
	public String getUserById(Integer userId) {
		return baseMapper.getUserById(userId);
	}


}
